﻿namespace PropOnline.Models.Validation
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Web.Helpers;
    using System.Web.Mvc;
    using PropOnline.Helpers;
    using PropOnline.Models;

    [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
    public class RequiredIfTipoPropiedadAttribute : ValidationAttribute, IClientValidatable
    {
        private string tipoPropiedadField;

        public RequiredIfTipoPropiedadAttribute(string tipoPropiedadField)
        {
            this.tipoPropiedadField = tipoPropiedadField;
        }

        public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
        {
            var rule = new ModelClientValidationRule
            {
                ValidationType = "requireiftipopropiedad",
                ErrorMessage = this.ErrorMessageString
            };

            rule.ValidationParameters.Add("otherfield", this.tipoPropiedadField);            
            rule.ValidationParameters.Add("tipospropiedadesquerequieren", Json.Encode(EnumExtensions.GetNames(PropOnlineConstants.TiposQueRequirenAmbientes)));

            yield return rule;
        }

        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            if (value == null)
            {
                var property = validationContext.ObjectInstance.GetType().GetProperty(this.tipoPropiedadField);

                if (property.PropertyType != typeof(TipoPropiedad) && property.PropertyType != typeof(TipoPropiedad?))
                {
                    throw new InvalidOperationException("The RequiredIfTipoPropiedad Validator can only be used with TipoPropiedad properties.");
                }

                var propertyValue = property.GetValue(validationContext.ObjectInstance, null);

                if (propertyValue != null && PropOnlineConstants.TiposQueRequirenAmbientes.Contains((TipoPropiedad)propertyValue))
                {
                    return new ValidationResult(this.ErrorMessageString);
                }
            }

            return ValidationResult.Success;
        }
    }
}